using Microsoft.EntityFrameworkCore;
using UniversalAdmin.Domain.Entities;
using UniversalAdmin.Domain.Repositories;
using UniversalAdmin.Infrastructure.Data.Contexts;
using UniversalAdmin.Shared.Enums;

namespace UniversalAdmin.Infrastructure.Repositories;

public class ArticleRepository : Repository<Article>, IArticleRepository
{
    public ArticleRepository(ApplicationDbContext context) : base(context)
    {
    }

    public async Task<(IEnumerable<Article> Articles, int TotalCount)> GetPagedAsync(int page, int pageSize, ArticleStatus? status = null, Guid? categoryId = null, string? keyword = null)
    {
        var query = _context.Articles
            .Include(a => a.Category)
            .Include(a => a.Author)
            .AsQueryable();

        if (status.HasValue)
        {
            query = query.Where(a => a.Status == status.Value);
        }

        if (categoryId.HasValue)
        {
            query = query.Where(a => a.CategoryId == categoryId.Value);
        }

        if (!string.IsNullOrEmpty(keyword))
        {
            query = query.Where(a =>
                a.Title.Contains(keyword) ||
                a.Content.Contains(keyword) ||
                a.Summary!.Contains(keyword));
        }

        var totalCount = await query.CountAsync();
        var articles = await query
            .OrderByDescending(a => a.CreatedAt)
            .Skip((page - 1) * pageSize)
            .Take(pageSize)
            .ToListAsync();

        return (articles, totalCount);
    }

    public async Task<IEnumerable<Article>> GetByCategoryAsync(Guid categoryId, int page, int pageSize)
    {
        return await _context.Articles
            .Include(a => a.Category)
            .Include(a => a.Author)
            .Where(a => a.CategoryId == categoryId)
            .OrderByDescending(a => a.CreatedAt)
            .Skip((page - 1) * pageSize)
            .Take(pageSize)
            .ToListAsync();
    }

    public async Task<IEnumerable<Article>> GetByAuthorAsync(Guid authorId, int page, int pageSize)
    {
        return await _context.Articles
            .Include(a => a.Category)
            .Include(a => a.Author)
            .Where(a => a.AuthorId == authorId)
            .OrderByDescending(a => a.CreatedAt)
            .Skip((page - 1) * pageSize)
            .Take(pageSize)
            .ToListAsync();
    }
}

public class ArticleCategoryRepository : Repository<ArticleCategory>, IArticleCategoryRepository
{
    public ArticleCategoryRepository(ApplicationDbContext context) : base(context)
    {
    }

    public async Task<bool> HasChildrenAsync(Guid id)
    {
        return await _context.ArticleCategories.AnyAsync(c => c.ParentId == id);
    }

    public async Task<bool> HasArticlesAsync(Guid id)
    {
        return await _context.Articles.AnyAsync(a => a.CategoryId == id);
    }

    public async Task<IEnumerable<ArticleCategory>> GetByIdsAsync(IEnumerable<Guid> ids)
    {
        return await _context.ArticleCategories
            .Where(c => ids.Contains(c.Id))
            .ToListAsync();
    }
}